package com.hoapital.outpbillwork.function;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hoapital.outpbillwork.module.controller.dto.OrderDetail;
import com.hoapital.outpbillwork.module.controller.dto.OrderQuery;
import com.hoapital.outpbillwork.module.controller.dto.OrderQueryAll;
import com.hoapital.outpbillwork.module.controller.vo.OrderInfoRecive;
import com.hoapital.outpbillwork.module.service.*;
import com.hospital.api.RemoteDictionaryService;
import com.hospital.common.core.exception.ExceptionHelp;
import com.hoapital.outpbillwork.module.controller.dto.OrderSure;
import com.hoapital.outpbillwork.module.entity.*;
import com.hoapital.outpbillwork.module.service.*;
import com.hospital.common.core.result.ErrorTip;
import com.hospital.common.core.result.SuccessTip;
import com.hospital.common.core.result.Tip;
import com.hospital.common.core.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author lvyao
 * @description 数据查询方法
 * @date 2022/3/7
 */
@Slf4j
@Service
public class SelectData {
    @Resource
    private OutpOrderDescTempService outpOrderDescTempService;

    @Resource
    private OutpOrderDescService outpOrderDescService;

    @Resource
    private OutpDoctorAssistantService outpDoctorAssistantService;

    @Resource
    private OutpPrepayRcptTempService outpPrepayRcptTempService;

    @Resource
    private ClinicMasterService clinicMasterService;

    @Resource
    private OutpBillItemsTempService outpBillItemsTempService;

    @Resource
    private OutpDoctorPrescItemsService outpDoctorPrescItemsService;

    @Resource
    private OutpDoctorPrescMasterService outpDoctorPrescMasterService;

    @Resource
    private PatientInfoService patientInfoService;

    @Resource
    private OrderVsBillnoService orderVsBillnoService;

    @Resource
    private RemoteDictionaryService remoteDictionaryService;


    public Tip getOrderData(String requestVal) {
        Tip tip = new SuccessTip();
        OrderQueryAll orderQueryAll = new OrderQueryAll();
        OrderInfoRecive orderInfo = null;
        try {
            orderInfo = JSON.parseObject(requestVal, OrderInfoRecive.class);
        } catch (Exception e) {
            tip = new ErrorTip("1001", "入参格式转换出错:" + e.getMessage());
            return tip;
        }
        if (orderInfo.getQuerySql() == null || orderInfo.getQuerySql().trim().equals("")) {
            orderInfo.setQuerySql(DateUtil.getDay());
        }
        List<OrderQuery> orderQueryList = new ArrayList<>();
        List<OutpPrepayRcptTemp> outpPrepayRcptTempList = new ArrayList<>();
        String sql = orderInfo.getQuerySql();
        PatientInfo patInfo = null;
        try {
            if (orderInfo.getType() != null && orderInfo.getType().equals("5")) {
                OutpPrepayRcptTemp outpPrepayRcptTemp = outpPrepayRcptTempService.getOne(new QueryWrapper<OutpPrepayRcptTemp>().eq("order_no", sql));
                patInfo = patientInfoService.getById(outpPrepayRcptTemp.getPatientId());
                outpPrepayRcptTempList.add(outpPrepayRcptTemp);
                orderQueryAll.setOutpPrepayRcptTemp(outpPrepayRcptTempList);
            } else {
                patInfo = orderInfo.getPatInfo();
            }
            if (orderInfo.getType() != null && orderInfo.getType().equals("6")) {
                outpPrepayRcptTempList = outpPrepayRcptTempService.list(new QueryWrapper<OutpPrepayRcptTemp>().apply("patient_id={0} and ESB_TRAN_STATUS = '1' and HIS_TRAN_STATUS = '1' and ESB_TRANSACT_DATE > to_Date({1},'yyyy-mm-dd') " +
                        "and  ESB_TRANSACT_DATE < to_Date({2},'yyyy-mm-dd') and TRANSACT_TYPE ='结算'  and order_no is not null", patInfo.getPatientId(), sql.split(",")[0], sql.split(",")[1]));
                orderQueryAll.setOutpPrepayRcptTemp(outpPrepayRcptTempList);
                tip.setData(orderQueryAll);
                return tip;
            }
            List<ClinicMaster> clinicMasterList = null;
            if (orderInfo.getType() == null || orderInfo.getType().equals("1")) {
                clinicMasterList = clinicMasterService.list(new QueryWrapper<ClinicMaster>().apply("patient_id={0}  and visit_date >= to_Date({1},'yyyy-mm-dd') order by visit_date desc", patInfo.getPatientId(), sql));

            } else if (orderInfo.getType() != null && orderInfo.getType().equals("4")) {
                if (!outpPrepayRcptTempService.updateFlag(patInfo.getPatientId(), sql)) {
                    return new ErrorTip("1001", "更新订单有校标记失败！");
                }
                return new SuccessTip();
            } else {
                orderQueryList.add(getQueryList(sql, orderInfo.getType()));
                orderQueryAll.setOutpPrepayRcptTemp(outpPrepayRcptTempService.getSingleBill(sql));
            }

            if (clinicMasterList != null) {
                for (ClinicMaster clinicMaster : clinicMasterList) {
                    OrderQuery orderQuery = new OrderQuery();
                    orderQuery.setVisitId(String.valueOf(clinicMaster.getOutpId()));
                    String clinicBillNo = null;
                    //查询此次就诊的所有计费及未计费数据
                    List<OutpOrderDescTemp> outpOrderDescTempList = outpOrderDescTempService.list(new QueryWrapper<OutpOrderDescTemp>().
                            apply("patient_id={0}  and outp_id = {1} order by visit_date desc", patInfo.getPatientId(), clinicMaster.getOutpId()));
                    List<OutpOrderDesc> outpOrderDescList = outpOrderDescService.list(new QueryWrapper<OutpOrderDesc>().
                            apply("patient_id={0}  and outp_id = {1} order by visit_date desc", patInfo.getPatientId(), clinicMaster.getOutpId()));

                    if ((outpOrderDescTempList != null && outpOrderDescTempList.size() > 0) || (outpOrderDescList != null && outpOrderDescList.size() > 0)) {
                        //获取计费及未计费的billNo
                        String unBillNo = outpOrderDescTempList.stream().map(t -> {
                            String dateVisit = DateUtil.formatDate(t.getVisitDate(), "yyyyMMddHHmmss");
                            String visitNo = String.valueOf(t.getVisitNo());
                            return dateVisit + visitNo;
                        }).collect(Collectors.joining(","));
                        String billNo = outpOrderDescList.stream().map(t -> {
                            String dateVisit = DateUtil.formatDate(t.getVisitDate(), "yyyyMMddHHmmss");
                            String visitNo = String.valueOf(t.getVisitNo());
                            return dateVisit + visitNo;
                        }).collect(Collectors.joining(","));
                        //获取单次就诊的医嘱及明细项目
                        clinicBillNo = billNo == null ? unBillNo == null ? "" : unBillNo : unBillNo == null ? billNo : unBillNo + "," + billNo;
                        orderQuery = getQueryList(clinicBillNo, orderInfo.getType());
                    }
                    orderQueryList.add(orderQuery);
                }
            }
            if ((orderQueryList == null || orderQueryList.size() <= 0) && !orderInfo.getType().equals("5")) {
                tip = new ErrorTip("1003", "从入参中获取条件无查询结果！");
                return tip;
            }
        } catch (Exception e) {
            tip = new ErrorTip("1004", "从入参中获取条件查询结果失败！" + e.getMessage());
            return tip;
        }
        orderQueryAll.setOrderQueryList(orderQueryList);
        tip.setData(orderQueryAll);
        return tip;
    }

    public Tip getOrderSure(String requestVal) {
        Tip tip = new SuccessTip();
        OrderSure orderSure = new OrderSure();
        try {
            orderSure = JSON.parseObject(requestVal, OrderSure.class);

        } catch (Exception e) {
            tip = new ErrorTip("1001", "入参格式转换出错:" + e.getMessage());
            return tip;
        }
        PatientInfo patInfo = orderSure.getPatInfo();
        if (patInfo.getPatientId() == null || orderSure.getHisBillNo() == null || orderSure.getHisBillNo().size() == 0) {
            tip = new ErrorTip("1002", "入参中无患者ID或需合并的HIS业务单号，请检查入参！");
            return tip;
        }
        if (orderSure.getCreateChannel() == null || orderSure.getCreateChannel().trim().equals("")) {
            tip = new ErrorTip("1004", "入参中无创建渠道，请检查入参！");
            return tip;
        }
        if (orderSure.getSettleFlag() == null || orderSure.getOutpOrInp() == null) {
            tip = new ErrorTip("1005", "入参中无结算标识或门诊住院标识，请检查入参！");
            return tip;
        }
        OutpPrepayRcptTemp outpPrepayRcptTemp = null;
        List<OutpPrepayRcptTemp> outpPrepayRcptTempList = new ArrayList<>();
        try {
            BigDecimal costs = new BigDecimal("0");
            BigDecimal charges = new BigDecimal("0");
            List<String> orderbillNoList = orderSure.getHisBillNo();
            for (String billNo : orderSure.getHisBillNo()) {
                List<OutpBillItemsTemp> outpBillItemsTempList = outpBillItemsTempService.list(new QueryWrapper<OutpBillItemsTemp>().
                        apply("visit_date = to_Date({0},'yyyy-mm-dd hh24:mi:ss') and visit_no = {1}", billNo.substring(0, 14), billNo.substring(14)));
                if (outpBillItemsTempList == null || outpBillItemsTempList.size() == 0) {
                    tip = new ErrorTip("1003", "入参中" + billNo + "无需合并的HIS业务数据，请检查入参！");
                    return tip;
                }
                costs = costs.add(outpBillItemsTempList.stream().map(aa -> aa.getCosts()).reduce(BigDecimal.ZERO, BigDecimal::add));
                charges = charges.add(outpBillItemsTempList.stream().map(aa -> aa.getCharges()).reduce(BigDecimal.ZERO, BigDecimal::add));
            }
            Map<String, Object> map = outpPrepayRcptTempService.ceateOrderInfo(patInfo.getPatientId(), orderSure, charges);
            if (!map.get("code").equals("0000")) {
                tip = new ErrorTip((String) map.get("code"), "传送的HIS业务单号已有未支付订单包含，详情见data", map.get("outpPrepayRcptTemp"));
                return tip;
            }
            outpPrepayRcptTemp = (OutpPrepayRcptTemp) map.get("outpPrepayRcptTemp");
        } catch (ExceptionHelp e) {
            tip = new ErrorTip(String.valueOf(e.getCode()), e.getMessage());
            return tip;
        }
        tip.setData(outpPrepayRcptTemp);
        return tip;
    }

    public OrderQuery getQueryList(String sqlValue, String type) {
        List<OutpOrderDescTemp> outpOrderDescTempList = null;
        List<OutpOrderDesc> orderDescList = null;
        List<Map<String, Object>> objectList = new ArrayList<>();
        String[] split = null;
        if (type.equals("5")) {
            sqlValue = orderVsBillnoService.list(new QueryWrapper<OrderVsBillno>().eq("Order_no", sqlValue)).stream().map(OrderVsBillno::getBillNo).collect(Collectors.joining(","));
        }
        split = sqlValue.split(",");
        if (split.length == 0) {
            return null;
        }
        for (String sql : split) {
            if (!sql.equals("") && sql != null) {
                String visitDate = sql.substring(0, 14);
                String visitNo = sql.substring(14);
                outpOrderDescTempList = outpOrderDescTempService.list(new QueryWrapper<OutpOrderDescTemp>().
                        apply("  visit_date = to_Date({0},'yyyy-mm-dd hh24:mi:ss') and visit_no = {1} order by visit_date desc", visitDate, visitNo));
                orderDescList = outpOrderDescService.list(new QueryWrapper<OutpOrderDesc>().
                        apply("  visit_date = to_Date({0},'yyyy-mm-dd hh24:mi:ss') and visit_no = {1} order by visit_date desc", visitDate, visitNo));
                if (outpOrderDescTempList != null && outpOrderDescTempList.size() > 0) {
                    for (OutpOrderDescTemp outpOrderDescTemp : outpOrderDescTempList) {
                        int prescIndicator = outpOrderDescTemp.getPrescIndicator();
                        int verifyFlag = 1;
                        if (prescIndicator == 1) {
                            OutpDoctorPrescMaster outpDoctorPrescMaster = outpDoctorPrescMasterService.getOne(new QueryWrapper<OutpDoctorPrescMaster>().
                                    apply("  visit_date = to_Date({0},'yyyy-mm-dd hh24:mi:ss') and visit_no = {1} and rownum = 1", visitDate, visitNo));
                            verifyFlag = outpDoctorPrescMaster.getVerifyFlag();
                        }
                        if (verifyFlag == 1) {
                            Map<String, Object> map = new HashMap<>();
                            outpOrderDescTemp.setOrderedByDeptName(remoteDictionaryService.getdeptDictList().stream().filter(p -> p.getDeptCode().equals(outpOrderDescTemp.getOrderedByDept())).collect(Collectors.toList()).get(0).getDeptName());
                            map.put("visit_date", outpOrderDescTemp.getVisitDate());
                            map.put("visit_no", outpOrderDescTemp.getVisitNo());
                            map.put("outp_id", outpOrderDescTemp.getOutpId());
                            map.put("type", "2");
                            outpOrderDescTemp.setChargeFlag(0);
                            map.put("outpOrderDescTemp", outpOrderDescTemp);
                            objectList.add(map);
                        }
                    }
                } else if (orderDescList != null && orderDescList.size() > 0) {
                    for (OutpOrderDesc outpOrderDesc : orderDescList) {
                        Map<String, Object> map = new HashMap<>();
                        outpOrderDesc.setOrderedByDeptName(remoteDictionaryService.getdeptDictList().stream().filter(p -> p.getDeptCode().equals(outpOrderDesc.getOrderedByDept())).collect(Collectors.toList()).get(0).getDeptName());
                        map.put("visit_date", outpOrderDesc.getVisitDate());
                        map.put("visit_no", outpOrderDesc.getVisitNo());
                        map.put("outp_id", outpOrderDesc.getOutpId());
                        map.put("type", "3");
                        outpOrderDesc.setChargeFlag(1);
                        map.put("outpOrderDescTemp", outpOrderDesc);
                        objectList.add(map);
                    }
                }
            }
        }
        OrderQuery orderQuery = new OrderQuery();
        if (objectList != null && objectList.size() > 0) {
            orderQuery.setVisitId(String.valueOf(objectList.get(0).get("outp_id")));
            List<OrderDetail> orderDetailList = new ArrayList<>();
            for (Map<String, Object> map : objectList) {
                String visit_date = (String) map.get("visit_date");
                String visit_no = (String) map.get("visit_no");
                String sql = " visit_date =  to_Date({0},'yyyy-mm-dd hh24:mi:ss') and visit_no = {1}";
                Object outpOrderDescTemp = map.get("outpOrderDescTemp");
                String prescIndicator = JSON.parseObject(JSON.toJSONString(outpOrderDescTemp)).getString("prescIndicator");
                OrderDetail orderDetail = new OrderDetail();
                if (prescIndicator.equals("1")) {
                    List<OutpDoctorPrescItems> outpDoctorPrescItemsList = outpDoctorPrescItemsService.list(new QueryWrapper<OutpDoctorPrescItems>().apply(sql, visit_date, visit_no));
                    if (outpDoctorPrescItemsList != null && outpDoctorPrescItemsList.size() > 0) {
                        orderDetail.setOutpOrderDescTemp(outpOrderDescTemp);
                        List<Object> outpDoctorPrescItemsList1 = new ArrayList<>();
                        for (OutpDoctorPrescItems outpDoctorPrescItems : outpDoctorPrescItemsList) {
                            outpDoctorPrescItems.setItemClassName(remoteDictionaryService.getclinicItemClassDictList().stream().filter(p -> p.getClassCode().equals(outpDoctorPrescItems.getItemClass())).collect(Collectors.toList()).get(0).getClassName());
                            outpDoctorPrescItems.setPerformedByName(remoteDictionaryService.getdeptDictList().stream().filter(p -> p.getDeptCode().equals(outpDoctorPrescItems.getPerformedBy())).collect(Collectors.toList()).get(0).getDeptName());
                            outpDoctorPrescItemsList1.add(outpDoctorPrescItems);
                        }
                        orderDetail.setOutpDoctorAssistantList(outpDoctorPrescItemsList1);
                        orderDetailList.add(orderDetail);
                    }
                } else {
                    List<OutpDoctorAssistant> outpDoctorAssistantList = outpDoctorAssistantService.list(new QueryWrapper<OutpDoctorAssistant>().apply(sql, visit_date, visit_no));
                    if (outpDoctorAssistantList != null && outpDoctorAssistantList.size() > 0) {
                        orderDetail.setOutpOrderDescTemp(outpOrderDescTemp);
                        List<Object> outpDoctorAssistantList1 = new ArrayList<>();
                        for (OutpDoctorAssistant outpDoctorAssistant : outpDoctorAssistantList) {
                            outpDoctorAssistant.setItemClassName(remoteDictionaryService.getclinicItemClassDictList().stream().filter(p -> p.getClassCode().equals(outpDoctorAssistant.getItemClass())).collect(Collectors.toList()).get(0).getClassName());
                            outpDoctorAssistant.setPerformedByName(remoteDictionaryService.getdeptDictList().stream().filter(p -> p.getDeptCode().equals(outpDoctorAssistant.getPerformedBy())).collect(Collectors.toList()).get(0).getDeptName());
                            outpDoctorAssistant.setDeptName(remoteDictionaryService.getdeptDictList().stream().filter(p -> p.getDeptCode().equals(outpDoctorAssistant.getDept())).collect(Collectors.toList()).get(0).getDeptName());
                            outpDoctorAssistantList1.add(outpDoctorAssistant);
                        }
                        orderDetail.setOutpDoctorAssistantList(outpDoctorAssistantList1);
                        orderDetailList.add(orderDetail);
                    }
                }
                orderQuery.setOrderDetailList(orderDetailList);
            }
        }
        return orderQuery;
    }
}
